2023/12/234875字符

组件

React 要求组件名首字母必须为大写

函数组件

import React from 'react';
import ReactDOM from 'react-dom';

function MyComp () {
    return (<div>函数组件</div>);
}

ReactDOM.render(<MyComp/>, document.getElementById('root'));

函数组件属性

import React from 'react';
import ReactDOM from 'react-dom';

function MyComp (props) {
    return (<div>类组件{props.number}</div>);
}

ReactDOM.render(<MyComp number={5}/>, document.getElementById('root'));

组件属性命名:小驼峰式命名

import React from 'react';
import ReactDOM from 'react-dom';

function MyComp (props) {
    return (<>
        <p>name: {props.name}</p>
        <p>age: {props.age}</p>
    </>);
}

const obj = {name: 'bozai', age: 18}
ReactDOM.render(<MyComp {...obj}/>, document.getElementById('root'));

所传递的属性都是只读的(单项数据流),不能再组件内部进行更改。我们也不要刻意的去更改他们(数据属于谁,谁才有权利改动)

数组渲染

import React from 'react';
import ReactDOM from 'react-dom';

function MyComp (props) {
    const list = props.arr.map((val, i) => {
        return (<div key={i}>
            <p>name:{val.name}</p>
            <p>age:{val.age}</p>
        </div>)
    })
    return list;
}

const arr = [
    {name: '张三', age: 18},
    {name: '李四', age: 88},
    {name: '王五', age: 26},
    {name: '赵六', age: 53}
]
ReactDOM.render(<MyComp arr={arr}/>, document.getElementById('root'));

类组件

import React from 'react';
import ReactDOM from 'react-dom';

class MyClassComp extends React.Component {  // 必须继承 React.Component,用于渲染组件
    render () {  // 类组件必须返回一个 render 函数
        return (<div>类组件</div>);
    }
}

ReactDOM.render(<MyClassComp/>, document.getElementById('root'));

类组件属性

import React from 'react';
import ReactDOM from 'react-dom';

class MyClassComp extends React.Component {
    // constructor (props) {
    //     super(props);  // this.props = porps
    // }
    render () {
        return (<div>类组件{this.props.number}</div>);
    }
}

ReactDOM.render(<MyClassComp number={5}/>, document.getElementById('root'));

类组件状态

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class Tick extends Component {
    constructor (props) {
        super(props);
        this.state = {
            left: this.props.num
        }
        this.timer = setInterval(() => {
            this.setState({  // 重新设置状态,自动触发重新渲染
                left: this.state.left - 1
            });
            if (this.state.left === 0) clearInterval(this.timer);
        }, 1000);
    }
    render () {
        return (<p>{this.state.left}</p>);
    }
}

ReactDOM.render(<Tick num={5}/>, document.getElementById('root'));

内容传递

import React from 'react';
import ReactDOM from 'react-dom';

function MyComp (props) {
    return (<>{props.children[0] || 'default'}</>);
}

ReactDOM.render(<MyComp>
    <h1>hello</h1>
    <h2>word</h2>
</MyComp>, document.getElementById('root'));

默认属性 & 类型检查

prop-types Usage

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types'

function MyComp (props) {
    return (<>{props.num}</>);
}
MyComp.defaultProps = {  // 设置传递属性默认值
    num: 1,
}
MyComp.propTypes = {  // 类型检查
    num: PropTypes.number.isRequired,  // 数字类型 && 必传项
    sex: PropTypes.oneOf(['男', '女']),  // 对象枚举(必须是数组其中一个)
    node: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),  // 必须是数组类型其中的一个
    arr: PropTypes.arrayOf(PropTypes.number),  // 规定所传数组每一项的类型
    obj1: PropTypes.shape({  // 规定对象内部键值类型(可以多传递)
        name: PropTypes.string,
        age: PropTypes.number,
        address: PropTypes.shape({
            city: PropTypes.string
        })
    }),
    obj2: PropTypes.exact({}),  // 精确对象键值类型
    reg: (props, propName, componentName) => {  // 自定义函数检查类型 
        if (props[propName] === undefined || null) {
            return new Error(`${propName} 为必传项`)
        }
        if (!/\d/.test(props[propName])) {
            return new Error(`${propName} 不符合正则要求`)
        }
    }
}

ReactDOM.render(<MyComp num={10} sex={'男'} reg={234}/>, document.getElementById('root'));